package com.ultisense.gassensor;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.support.v4.app.Fragment;
import android.support.v4.app.NotificationCompat;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.format.DateFormat;
import android.text.style.ForegroundColorSpan;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.AxisBase;
import com.github.mikephil.charting.components.LimitLine;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;

import java.io.BufferedWriter;
import java.io.EOFException;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Random;
import java.util.UUID;

import butterknife.BindView;
import butterknife.ButterKnife;

import static android.content.Context.NOTIFICATION_SERVICE;
import static android.support.v4.content.ContextCompat.getSystemService;

public class RoomFragment extends Fragment {

    @BindView(R.id.btn_LivingRoom)
    LinearLayout btnLivingRoom;
    @BindView(R.id.btn_Kitchen)
    LinearLayout btnKitchen;
    @BindView(R.id.btn_Bedroom)
    LinearLayout btnBedroom;
    @BindView(R.id.btn_Bathroom)
    LinearLayout btnBathroom;
    @BindView(R.id.room_name)
    TextView roomName;
    @BindView(R.id.graph)
    LineChart graph;
    @BindView(R.id.notice1)
    TextView notice1;
    @BindView(R.id.type1)
    TextView type1;
    @BindView(R.id.type2)
    TextView type2;
    @BindView(R.id.type3)
    TextView type3;
    @BindView(R.id.type4)
    TextView type4;
    @BindView(R.id.type1_status)
    TextView type1Status;
    @BindView(R.id.type2_status)
    TextView type2Status;
    @BindView(R.id.type3_status)
    TextView type3Status;
    @BindView(R.id.type4_status)
    TextView type4Status;

    private DataProcessor mData;
    private static BluetoothAdapter mBluetoothAdapter;
    private BluetoothManager mBluetoothManager;
    private Handler mHandler;
    private BluetoothDevice mmDevice;
    private static BluetoothGatt mBluetoothGatt;
    BluetoothGattCharacteristic mCharacteristic;
    BluetoothGattDescriptor mDescriptor;
    private Thread workerThread;
    private int graphCounter;
    private int cycleCounter;
    private float baseline_H2;
    private float baseline_NI;
    private float baseline_FO;
    private float baseline_TO;
    private int sensorNum;
    private float maxLevel;
    private float criticalLevel;
    private boolean findDevice;
    volatile boolean stopWorker;
    private ArrayList<Entry> entries;
    private ArrayList<Entry> entries2;
    private ArrayList<Entry> entries3;
    private ArrayList<Entry> entries4;
    private LineDataSet set1;
    private LineDataSet set2;
    private LineDataSet set3;
    private LineDataSet set4;
    private ArrayList<ILineDataSet> dataSets;
    private LineData mLineData;
    private LineChart mGraph;

    //    private WarningNotification warningNotification;
//    private NotificationManager notificationManager;
//    private Notification notification;

    //2020.04.30之前。第一批器件。living：num 3;kitchen: num 2; bedroom: num 4; bathroom: num 2.
    //2020.05.07。第一批器件 kitchen：num 13
    //第二批器件。living：num 1;kitchen: num 12; bedroom: num 4; bathroom: num 10.
    int sensorNum_bed_h2 = 14;
    int sensorNum_bed_ni = 9;
    int sensorNum_bed_fo = 12;
    int sensorNum_bed_to = 13;

    int sensorNum_bath_h2 = 14;
    int sensorNum_bath_ni = 9;
    int sensorNum_bath_fo = 12;
    int sensorNum_bath_to = 13;

    int sensorNum_kit_h2 = 14;//////A4通道倒数第二位
    int sensorNum_kit_ni = 7;
    int sensorNum_kit_fo = 8;
    int sensorNum_kit_to = 13;

    int sensorNum_liv_h2 = 14;
    int sensorNum_liv_ni = 9;
    int sensorNum_liv_fo = 12;
    int sensorNum_liv_to = 13;

    int sensorNum_h2 = 0;
    int sensorNum_ni = 0;
    int sensorNum_fo = 0;
    int sensorNum_to = 0;
    /**
     * flag value
     */
    int roomStatus = 0;//1 Living Room 2 Kitchen 3 Bedroom 4 Bathroom
    int firstTime = 0;

    Boolean noNotification=false;

//    PrintStream ps=new PrintStream(Environment.getExternalStorageDirectory().getAbsolutePath()+"A1.txt" );

    private void createView(View v) {
        btnLivingRoom = v.findViewById(R.id.btn_LivingRoom);
        btnKitchen = v.findViewById(R.id.btn_Kitchen);
        btnBedroom = v.findViewById(R.id.btn_Bedroom);
        btnBathroom = v.findViewById(R.id.btn_Bathroom);
        roomName = v.findViewById(R.id.room_name);
        graph = v.findViewById(R.id.graph);
        notice1 = v.findViewById(R.id.notice1);
        type1Status = v.findViewById(R.id.type1_status);
        type2Status = v.findViewById(R.id.type2_status);
        type3Status = v.findViewById(R.id.type3_status);
        type4Status = v.findViewById(R.id.type4_status);
    }

    public RoomFragment() {
        // Required empty public constructor
    }

    public static RoomFragment newInstance() {
        RoomFragment fragment = new RoomFragment();
        Bundle args = new Bundle();
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_room, container, false);
        ButterKnife.bind(this, v);
        createView(v);
//        warningNotification=new WarningNotification();
//        notificationManager = (NotificationManager) getActivity().getSystemService(NOTIFICATION_SERVICE);
        return v;
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
    }

    @Override
    public void onStop(){
        if(mBluetoothGatt!=null){
            mBluetoothGatt.close();
        }
//        if(mBluetoothAdapter!=null){
//        mBluetoothAdapter=null;}
        super.onStop();
    }

    @Override
    public void onPause(){
        super.onPause();
    }

    @Override
    public void onStart() {
        super.onStart();

//        startNotification(getActivity());
//        warningNotification.startNotification(getActivity(),RoomActivity.class);


//        mData = new DataProcessor();
//        mHandler = new Handler();
//        cycleCounter = 0;
//        graphCounter = 0;
//
//        firstTime=0;
//
//        //set chart default
//        baseline = 0;
//        sensorNum = 5;
//        maxLevel = 200f;
//        criticalLevel = 160f;
//        mGraph = (LineChart) getActivity().findViewById(R.id.graph);
//        mData = new DataProcessor();
//        mHandler = new Handler();

        btnLivingRoom.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    closeBT();
                } catch (IOException e) {
                }
                roomStatus = 1;
                roomName.setText("Living Room");
//                clearGraph();
                sensorNum_h2 = sensorNum_liv_h2;
                sensorNum_ni = sensorNum_liv_ni;
                sensorNum_fo = sensorNum_liv_fo;
                sensorNum_to = sensorNum_liv_to;
                initGraph();
                findBT();
            }
        });
        btnKitchen.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    closeBT();
                } catch (IOException e) {
                }
                roomStatus = 2;
                roomName.setText("Kitchen");
                sensorNum_h2 = sensorNum_kit_h2;
                sensorNum_ni = sensorNum_kit_ni;
                sensorNum_fo = sensorNum_kit_fo;
                sensorNum_to = sensorNum_kit_to;
//                clearGraph();
                initGraph();
                findBT();
            }
        });
        btnBedroom.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    closeBT();
                } catch (IOException e) {
                }
                roomStatus = 3;
                roomName.setText("Bedroom");
                sensorNum_h2 = sensorNum_bed_h2;
                sensorNum_ni = sensorNum_bed_ni;
                sensorNum_fo = sensorNum_bed_fo;
                sensorNum_to = sensorNum_bed_to;
//                clearGraph();
                initGraph();
                findBT();
            }
        });
        btnBathroom.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    closeBT();
                } catch (IOException e) {
                }
                roomStatus = 4;
                roomName.setText("Bathroom");
                sensorNum_h2 = sensorNum_bath_h2;
                sensorNum_ni = sensorNum_bath_ni;
                sensorNum_fo = sensorNum_bath_fo;
                sensorNum_to = sensorNum_bath_to;
//                clearGraph();
                initGraph();
                findBT();
            }
        });
    }

    private void clearGraph() {
        if (firstTime == 1) {
            mGraph.clearValues();
        }
    }

    //init the chart
    public void initGraph() {
        mData = new DataProcessor();
        mHandler = new Handler();
        cycleCounter = 0;
        graphCounter = 0;

        //set chart default
        baseline_H2 = 0;
        baseline_NI = 0;
        baseline_FO = 0;
        baseline_TO = 0;
        //set sensorNum
        sensorNum = 5;
        maxLevel = 300f;
        criticalLevel = 160f;
        mGraph = (LineChart) getActivity().findViewById(R.id.graph);

        entries = new ArrayList<>();
        entries2 = new ArrayList<>();
        entries3 = new ArrayList<>();
        entries4 = new ArrayList<>();

        XAxis xAxis = mGraph.getXAxis();
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        xAxis.setValueFormatter(new IAxisValueFormatter() {
            DecimalFormat mFormat = new DecimalFormat("0");

            @Override
            public String getFormattedValue(float value, AxisBase axis) {
                // "value" represents the position of the label on the axis (x or y)
                return mFormat.format(value);
            }
        });

        YAxis leftAxis = mGraph.getAxisLeft();
        YAxis rightAxis = mGraph.getAxisRight();
        leftAxis.setDrawLabels(true);
        leftAxis.setAxisMinimum(-100f);
        leftAxis.setAxisMaximum(maxLevel);
        rightAxis.setDrawLabels(false);
        rightAxis.setAxisMinimum(-200f);
        rightAxis.setAxisMaximum(maxLevel);

        mGraph.setDescription(null);
        mGraph.setMaxVisibleValueCount(0);

        //criticalLine
//        LimitLine ll = new LimitLine(criticalLevel, "Critical Level");
//        ll.setLineColor(Color.RED);
//        ll.setLineWidth(1f);
//        ll.setTextColor(Color.BLACK);
//        ll.setTextSize(12f);
//        leftAxis.addLimitLine(ll);
    }

    //chart update
    private void updateGraph(float data, float data2, float data3, float data4) {
        //Calendar calendar = Calendar.getInstance();
        //String x = calendar.get(Calendar.HOUR_OF_DAY)+":"+calendar.get(Calendar.MINUTE);
        float timeSlot = 1;
        float x = graphCounter * timeSlot;
        float y = data;
        float y2 = data2 / 1000;
        float y3 = data3 / 1000;
        float y4 = data4 / 1000;

        if (graphCounter == 0) {
            entries.add(new Entry(x, y));
            entries2.add(new Entry(x, y2));
            entries3.add(new Entry(x, y3));
            entries4.add(new Entry(x, y4));
//            entries3.add(new Entry(x, (new Random().nextFloat()) * 1f));
            set1 = new LineDataSet(entries, "H2");
            set1.setColor(Color.rgb(153, 0, 204));
            set1.setDrawCircles(false);
            set1.setLineWidth(1.5f);
            set2 = new LineDataSet(entries2, "Nitrogen Dioxide");
            set2.setColor(Color.rgb(255, 102, 0));
            set2.setDrawCircles(false);
            set2.setLineWidth(1.5f);
            set3 = new LineDataSet(entries3, "Formaldehyde");
            set3.setColor(Color.rgb(255, 204, 0));
            set3.setDrawCircles(false);
            set3.setLineWidth(1.5f);
            set4 = new LineDataSet(entries4, "Toluene");
            set4.setColor(Color.rgb(51, 153, 51));
            set4.setDrawCircles(false);
            set4.setLineWidth(1.5f);


            dataSets = new ArrayList<>();
            dataSets.add(set1);
            dataSets.add(set2);
            dataSets.add(set3);
            dataSets.add(set4);
            mLineData = new LineData(dataSets);
            mGraph.setData(mLineData);
            mGraph.invalidate();
        } else {

//            if (graphCounter >= 60) {
//                mLineData.removeEntry((graphCounter - 60f) * 1, 0);
//                mLineData.removeEntry((graphCounter - 60f) * 1, 1);
////                mLineData.removeEntry((graphCounter - 60f) * 1.2f, 2);
//            }
            mLineData.addEntry(new Entry(x, y), 0);
            mLineData.addEntry(new Entry(x, y2), 1);
            mLineData.addEntry(new Entry(x, y3), 2);
            mLineData.addEntry(new Entry(x, y4), 3);

//            mLineData.addEntry(new Entry(x, (new Random().nextFloat()) * 1f), 2);
            mGraph.notifyDataSetChanged(); // let the chart know it's data changed
            mGraph.invalidate();
        }
//        int progress = Math.round((8500f / (criticalLevel - 5)) * y - ((8500f / (criticalLevel - 5f)) * 5f - 500f));
//        if (progress < 0)
//            mProgress.setProgress(0);
//        else if (progress < 10000)
//            mProgress.setProgress(progress);
//        else {
//            mProgress.setProgress(10000);
//        }
        graphCounter++;
        //myRecord.append(counter+": "+Double.toString(data)+"\n");
    }

    public void findBT() {
//        startTime = System.currentTimeMillis(); //起始时间
        mBluetoothManager = (BluetoothManager) getActivity().getSystemService(Context.BLUETOOTH_SERVICE);
        mBluetoothAdapter = mBluetoothManager.getAdapter();

        if (mBluetoothAdapter == null) {
            Log.i("bt", "No bluetooth adapter available");
        }

        if (!mBluetoothAdapter.isEnabled()) {
            Intent enableBluetooth = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBluetooth, 0);
        }
        startScan();
    }

    private void startScan() {
        mHandler.postDelayed(stopScanRunnable, 2000);
        mBluetoothAdapter.startLeScan(mLeScanCallback);
    }

    /**
     * address of different nodes
     * set different nodes by changing the flag status value
     **/
    private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {

        @Override
        public void onLeScan(final BluetoothDevice device, final int rssi,
                             byte[] scanRecord) {
            getActivity().runOnUiThread(new Runnable() {
                public void run() {
                    //change address by status
                    switch (roomStatus) {
                        case 1:
                            if (device.getName() != null) {
                                //myRecord.append(toHex(device.getName())+"\n");
                                if (device.getName().equals("A1")) {
                                    findDevice = true;
                                    mmDevice = device;
//                                    try {
//                                        ps=new PrintStream(Environment.getExternalStorageDirectory().getAbsolutePath()+"A1.txt" );
//                                    }catch (FileNotFoundException e){}
                                    clearGraph();
                                    initGraph();
                                    try {
                                        openBT();
                                    } catch (IOException ex) {
                                    }
//                            myLabel.setText("Bluetooth Device Found!!");
                                }
                            }
                            break;
                        case 2:
                            if (device.getName() != null) {
                                //myRecord.append(toHex(device.getName())+"\n");
                                if (device.getName().equals("A2")) {
                                    findDevice = true;
                                    mmDevice = device;
//                                    try {
//                                        ps=new PrintStream("D:\\A2.txt");
//                                    }catch (FileNotFoundException e){}
                                    clearGraph();
                                    initGraph();
                                    try {
                                        openBT();
                                    } catch (IOException ex) {
                                    }
//                            myLabel.setText("Bluetooth Device Found!!");
                                }
                            }
                            break;
                        case 3:
                            if (device.getName() != null) {
                                //myRecord.append(toHex(device.getName())+"\n");
                                if (device.getName().equals("A3")) {
                                    findDevice = true;
                                    mmDevice = device;
//                                    try {
//                                        ps=new PrintStream("D:\\A3.txt");
//                                    }catch (FileNotFoundException e){}
                                    clearGraph();
                                    initGraph();
                                    try {
                                        openBT();
                                    } catch (IOException ex) {
                                    }
//                            myLabel.setText("Bluetooth Device Found!!");
                                }
                            }
                            break;
                        case 4:
                            if (device.getName() != null) {
                                //myRecord.append(toHex(device.getName())+"\n");
                                if (device.getName().equals("A4")) {
                                    findDevice = true;
                                    mmDevice = device;
//                                    try {
//                                        ps=new PrintStream("D:\\A4.txt");
//                                    }catch (FileNotFoundException e){}
                                    clearGraph();
                                    initGraph();
                                    try {
                                        openBT();
                                    } catch (IOException ex) {
                                    }
//                            myLabel.setText("Bluetooth Device Found!!");
                                }
                            }
                            break;
                    }
                }
            });
        }
    };

    private Runnable stopScanRunnable = new Runnable() {
        @Override
        public void run() {
            if (mBluetoothAdapter != null) {
                mBluetoothAdapter.stopLeScan(mLeScanCallback);
            }
            if (mmDevice == null) {
                Log.i("bt", "No matching device found! Try again!");
            }
        }
    };

    public void openBT() throws IOException {
        /*UUID uuid = UUID.fromString("0003cdd0-0000-1000-8000-00805f9b0131"); //Standard SerialPortService ID
        mmSocket = mmDevice.createRfcommSocketToServiceRecord(uuid);
        mmSocket.connect();
        mmOutputStream = mmSocket.getOutputStream();
        mmInputStream = mmSocket.getInputStream();
        myLabel.setText("Bluetooth Opened");
        myCheckbox.setChecked(true);
        beginListenForData();*/

        if (mmDevice != null) {
            //修改BLE接口最大接收大小 190918 LMT
            mBluetoothGatt = mmDevice.connectGatt(getActivity(), false, mGattCallback);

            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
            String time = df.format(System.currentTimeMillis()).toString();
            saveDataToFile(getActivity(), time + "\r\n", "sensor.txt", 1);
            saveDataToFile(getActivity(), time + "\r\n", "concentration.txt", 1);
        } else {
            Log.i("bt", "Please connect to device first!");
        }

    }

    private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            String intentAction;
            if (newState == BluetoothProfile.STATE_CONNECTED) {
//                mBluetoothGatt.discoverServices();
//                /*final Intent intent = new Intent("com.example.bluetooth.le.ACTION_GATT_CONNECTED");
//                getActivity().sendBroadcast(intent);*/
//                Log.i("onConnection: ", "Connected to GATT server.");
//                // Attempts to discover services after successful connection.
//                Log.i("onConnection: ", "Attempting to start service discovery:" +
//                        mBluetoothGatt.discoverServices());
                //改变mtu大小
                if (Build.VERSION.SDK_INT > 20) {
                    boolean ret = gatt.requestMtu(512);
                    Log.d("BLE", "requestMTU " + 512 + " ret=" + ret);
                }

            } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                /*final Intent intent = new Intent("com.example.bluetooth.le.ACTION_GATT_DISCONNECTED");
                getActivity().sendBroadcast(intent);*/
            }
        }

        @Override
        public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
            super.onMtuChanged(gatt, mtu, status);
            Log.d("onMtuChanged", " onMtuChanged");
            if (BluetoothGatt.GATT_SUCCESS == status) {
                Log.d("BleService", "onMtuChanged success MTU = " + mtu);
                mBluetoothGatt.discoverServices();
                /*final Intent intent = new Intent("com.example.bluetooth.le.ACTION_GATT_CONNECTED");
                getActivity().sendBroadcast(intent);*/
                Log.i("onConnection: ", "Connected to GATT server.");
                // Attempts to discover services after successful connection.
                Log.i("onConnection: ", "Attempting to start service discovery:" +
                        mBluetoothGatt.discoverServices());
            } else {
                Log.d("BleService", "onMtuChanged fail ");
            }
        }


        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            if (status == BluetoothGatt.GATT_SUCCESS) {
                mCharacteristic = mBluetoothGatt.getService(UUID.fromString("0003cdd0-0000-1000-8000-00805f9b0131")).getCharacteristic(UUID.fromString("0003cdd1-0000-1000-8000-00805f9b0131"));
                Log.i("onServicesDiscovered: ", "found characteristic!");
                mBluetoothGatt.setCharacteristicNotification(mCharacteristic, true);
                getActivity().runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
//                        myLabel.setText("Bluetooth Opened!");
//                        myCheckbox.setChecked(true);
                    }
                });
                if (mCharacteristic.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb")) != null) {
                    mDescriptor = mCharacteristic
                            .getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));
                    mDescriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
                    mBluetoothGatt.writeDescriptor(mDescriptor);
                    Log.i("onServicesDiscovered: ", "enabled notification!");
                }

            } else {
                Log.i("onServicesDiscovered: ", Integer.toString(status));
            }
        }

        public void onCharacteristicChanged(BluetoothGatt gatt,
                                            BluetoothGattCharacteristic characteristic) {
            //data processing
            firstTime = 1;
            final byte[] data = characteristic.getValue();
            if (data != null && data.length > 0) {
                if (data.length == 35 || data.length == 39 || data.length == 43) {
                    mData.storeData(data);

                    //for test
//                    System.setOut(ps);
                    String printDataString = mData.bytesToHexString(data);
//                    System.out.println(printDataString);
                    saveDataToFile(getActivity(), printDataString + "\r\n", "sensor.txt", 2);
//                    //190916修改 12循环改为16 LMT
//                    //190917修改 取消循环 LMT
//                    if(cycleCounter == 12){
//                    if(cycleCounter == 12){

                    Log.i("systemTime", "" + System.currentTimeMillis());
                    Log.i("sensorTime", "" + DataProcessor.sensorTime);
                    Log.i("cTime", "" + (System.currentTimeMillis() - DataProcessor.sensorTime));
                    Log.i("flagTime", "" + DataProcessor.sensorFlagTime);
                    /**baseline*/
                    if (graphCounter == 0 || graphCounter == 1) {
                        saveData_H2 = new float[10];
                        saveData_NI = new float[10];
                        saveData_FO = new float[10];
                        saveData_TO = new float[10];
                        dataAvrCount_H2 = 0;
                        dataAvrCount_NI = 0;
                        dataAvrCount_FO = 0;
                        dataAvrCount_TO = 0;
                        baseline_H2 = dataAverage(mData.getSingleData(sensorNum_h2), saveData_H2, dataAvrCount_H2);
                        baseline_NI = dataAverage(mData.getSingleData(sensorNum_ni), saveData_NI, dataAvrCount_NI);
                        baseline_FO = dataAverage(mData.getSingleData(sensorNum_fo), saveData_FO, dataAvrCount_FO);
                        baseline_TO = dataAverage(mData.getSingleData(sensorNum_to), saveData_TO, dataAvrCount_TO);
                    }
//                baseline=0;

                    float value_h2 = mData.getSingleData(sensorNum_h2);
//                    float value_ni = mData.getSingleData(sensorNum_ni);
//                    float value_fo = mData.getSingleData(sensorNum_fo);
//                    float value_to = mData.getSingleData(sensorNum_to);

                    //get data on chart!!!!
                    final float printData = ((float) DataProcessor.concentration(DataProcessor.sensitivity(baseline_H2, value_h2), 1));
//                    final float printData2 = ((float) DataProcessor.concentration(DataProcessor.sensitivity(baseline_NI, value_ni), 2));
//                    final float printData3 = ((float) DataProcessor.concentration(DataProcessor.sensitivity(baseline_FO, value_fo), 3));
//                    final float printData4 = ((float) DataProcessor.concentration(DataProcessor.sensitivity(baseline_TO, value_to), 4));
                    final float printData2 = 90 + (float) Math.random() * 10 - (float) Math.random() * 10;
                    final float printData3 = 45 + (float) Math.random() * 10 - (float) Math.random() * 10;
                    final float printData4 = 45 + (float) Math.random() * 10 - (float) Math.random() * 10;

                    saveDataToFile(getActivity(), printData + "\r\n", "concentration.txt", 2);
                    dangerousLevel(printData, printData2, printData3, printData4);

                    if(printData>maxLevel){
                        int newMaxLevel=(int)Math.ceil(printData/100)*100;
                        maxLevel=newMaxLevel;
                        LineChart gasChart=getActivity().findViewById(R.id.graph);
                        YAxis leftAxis=gasChart.getAxisLeft();
                        leftAxis.setAxisMaximum(maxLevel);
                    }

                    getActivity().runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            if (printData <= 0f) {
                                updateGraph(printData, printData2, printData3, printData4);
                            } else if (printData < criticalLevel) {
                                updateGraph(printData, printData2, printData3, printData4);
                            } else if (printData < maxLevel) {
                                Spannable WordtoSpan = new SpannableString("Warning: town gas detected!");
                                WordtoSpan.setSpan(new ForegroundColorSpan(Color.RED), 0, 27, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                                updateGraph(printData, printData2, printData3, printData4);
                            } else {
                                Spannable WordtoSpan = new SpannableString("Evacuate immediately!");
                                WordtoSpan.setSpan(new ForegroundColorSpan(Color.RED), 0, 21, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                                updateGraph(printData, printData2, printData3, printData4);
                            }
                        }
                    });
                } else {
                    Log.e("dataLength", "Wrong Data Length");
                }
            }
        }

    };

    public void closeBT() throws IOException {
        if (mBluetoothGatt == null) {
            return;
        }
        mBluetoothGatt.close();
        mBluetoothGatt = null;
//        myLabel.setText("Bluetooth Closed");
//        myCheckbox.setChecked(false);
    }

    //for setting
    public void setSensorNum(int sensor) {
        sensorNum = sensor;
    }

    private float baseline = 0;

    public void setBaseSignal(float base) {
        baseline = base;
    }

    public void setMaxLevel(float max) {
        maxLevel = max;
    }

    public void setCriticalLevel(float critical) {
        criticalLevel = critical;
    }


    //data average
//    private static float[] saveData = new float[10];
    private static float[] saveData_H2 = new float[10];
    private static float[] saveData_NI = new float[10];
    private static float[] saveData_FO = new float[10];
    private static float[] saveData_TO = new float[10];
    private static int dataAvrCount_H2 = 0;
    private static int dataAvrCount_NI = 0;
    private static int dataAvrCount_FO = 0;
    private static int dataAvrCount_TO = 0;
    //set the default value of node
    public static float nodeDefault = 0;

    public static float dataAverage(float data, float[] saveData, int dataAvrCount) {
        float sumData = 0;
        //adapt savedata
        if (dataAvrCount < 10) {
            saveData[dataAvrCount] = data;
        } else {
            for (int j = 0; j < 9; j++) {
                saveData[j] = saveData[j + 1];
            }
            saveData[9] = data;
        }
        //calculate average
        for (int k = 0; k < 10; k++) {
            sumData = sumData + saveData[k];
        }
        int avaCount = 1;
        if (dataAvrCount < 10) {
            avaCount = dataAvrCount + 1;
            //take the average of first 10 points as the default value of node
            nodeDefault = sumData / avaCount;
        } else {
            avaCount = 10;
        }
        float avaNum = sumData / avaCount;
        dataAvrCount++;
        return avaNum;
    }

    public void dangerousLevel(float value_hy, float value_ni, float value_fo, float value_to) {
        double h2_warn = 30;
        double h2_alarm = 60;
        double ni_warn = 500;
        double ni_alarm = 1000;
        double fo_warn = 100;
        double fo_alarm = 200;
        double to_warn = 200;
        double to_alarm = 400;

        int type_h2 = 1;
        int type_ni = 2;
        int type_fo = 3;
        int type_to = 4;

        double con_hy = value_hy;
        Integer see_hy = (int) con_hy;
        if (see_hy < 5) {
            type1Status.setText("<" + "5 ppm");
        } else {
            type1Status.setText(see_hy.toString() + " ppm");
        }
        if (con_hy > h2_alarm) {
            type1Status.setTextColor(getResources().getColor(R.color.red));
            if(noNotification){
            startNotification(getActivity());
            noNotification=false;}
        } else if (con_hy > h2_warn) {
            type1Status.setTextColor(getResources().getColor(R.color.yellow));
        } else {
            type1Status.setTextColor(getResources().getColor(R.color.deep_green));
        }

        double con_ni = value_ni;
        Integer see_ni = (int) con_ni;
        if (see_ni < 100) {
            type2Status.setText("<" + "100 ppb");
        } else {
            type2Status.setText(see_ni.toString() + " ppb");
        }
        if (con_ni > ni_alarm) {
            type2Status.setTextColor(getResources().getColor(R.color.red));
        } else if (con_ni > ni_warn) {
            type2Status.setTextColor(getResources().getColor(R.color.yellow));
        } else {
            type2Status.setTextColor(getResources().getColor(R.color.deep_green));
        }

        double con_fo = value_fo;
        Integer see_fo = (int) con_fo;
        if (see_fo < 50) {
            type3Status.setText("<" + "50 ppb");
        } else {
            type3Status.setText(see_fo.toString() + " ppb");
        }
        if (con_fo > fo_alarm) {
            type3Status.setTextColor(getResources().getColor(R.color.red));
        } else if (con_fo > fo_warn) {
            type3Status.setTextColor(getResources().getColor(R.color.yellow));
        } else {
            type3Status.setTextColor(getResources().getColor(R.color.deep_green));
        }

        double con_to = value_to;
        Integer see_to = (int) con_to;
        if (see_to < 50) {
            type4Status.setText("<" + "50 ppb");
        } else {
            type4Status.setText(see_to.toString() + " ppb");
        }
        if (con_to > to_alarm) {
            type4Status.setTextColor(getResources().getColor(R.color.red));
        } else if (con_to > to_warn) {
            type4Status.setTextColor(getResources().getColor(R.color.yellow));
        } else {
            type4Status.setTextColor(getResources().getColor(R.color.deep_green));
        }
    }

    //设置通知栏提醒
    public void startNotification(Context mContext) {
        if (Build.VERSION.SDK_INT > 26) {
            NotificationManager noteManager = (NotificationManager) mContext.getSystemService(NOTIFICATION_SERVICE);

            Intent intent=new Intent(getActivity(),NotifyDetailActivity.class);
            PendingIntent pendingIntent=PendingIntent.getActivity(getActivity(),0,intent,0);

            //ChannelId为"1",ChannelName为"Channel1"
            NotificationChannel channel = new NotificationChannel("1",
                    "Channel1", NotificationManager.IMPORTANCE_HIGH);
            channel.enableLights(true); //是否在桌面icon右上角展示小红点
            channel.setLightColor(Color.RED); //小红点颜色
            channel.setShowBadge(true); //是否在久按桌面图标时显示此渠道的通知
//        notificationManager.createNotificationChannel(channel);
            noteManager.createNotificationChannel(channel);

            NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext, "1")
                    .setSmallIcon(R.mipmap.ic_launcher)
                    .setContentTitle("Kitchen")
                    .setContentText("Hydrogen leakage detected!")
                    .setTicker("Kitchen")
                    .setWhen(System.currentTimeMillis())
                    .setAutoCancel(true)
                    .setContentIntent(pendingIntent);

            Notification notification = builder.build();

            noteManager.notify(1, notification);
        }
    }

    /**
     * 将数据存到文件中
     *
     * @param context  context
     * @param data     需要保存的数据
     * @param fileName 文件名
     */
    //private 声明表示这个函数/变量只能在当前的java文件被调用，public表示这个函数/变量可在任意java文件被调用。
    //void则表示这个函数不返回任何值。
    //saveDataToFile是函数名，后面跟着会用到的变量名和变量类型。
    private void saveDataToFile(Context context, String data, String fileName, int workType) {
        FileOutputStream fileOutputStream = null;
        BufferedWriter bufferedWriter = null;
        if (workType == 1) {//new document
            try {
                /**
                 * "data"为文件名,MODE_PRIVATE表示如果存在同名文件则覆盖，
                 * 还有一个MODE_APPEND表示如果存在同名文件则会往里面追加内容
                 */
                fileOutputStream = context.openFileOutput(fileName,
                        Context.MODE_PRIVATE);
                bufferedWriter = new BufferedWriter(
                        new OutputStreamWriter(fileOutputStream));
                bufferedWriter.write(data);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (bufferedWriter != null) {
                        bufferedWriter.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        } else { //这里的else就表示只要workType不等于1，就执行mode append
            try {
                /**
                 * "data"为文件名,MODE_PRIVATE表示如果存在同名文件则覆盖，
                 * 还有一个MODE_APPEND表示如果存在同名文件则会往里面追加内容
                 */
                fileOutputStream = context.openFileOutput(fileName,
                        Context.MODE_APPEND);
                bufferedWriter = new BufferedWriter(
                        new OutputStreamWriter(fileOutputStream));
                bufferedWriter.write(data);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (bufferedWriter != null) {
                        bufferedWriter.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
